; DESCRIPTION:
; Vertex shader used to render A3DMorphSkinMesh. this shader does below works:
; # vertex blending (4 morph channels and 1 bone matrix) and transform
; # compute light = env_ambient + dir_light(ambient & diffuse) + point_light(ambient & diffuse)
; # output texture coordinates

; CREATED BY: duyuxin, 2003/1/5
; Copyright (c) 2003 Archosaur Studio, All Rights Reserved.

vs.1.1

;------------------------------------------------------------------------------
; v0 	  = position
; v1 	  = blend weights
; v2 	  = blend indices
; v3 	  = normal
; v4 	  = texture coordinates
; v5-v6   = morph channel 0 position delta and normal delta
; v7-v8   = morph channel 1 position delta and normal delta
; v9-v10  = morph channel 2 position delta and normal delta
; v11-v12 = morph channel 3 position delta and normal delta
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Constants specified by the app;
;
; >= c15  = palette of world matrices (from model space to world space)
; c14     = palette of morph channel weight (4 weights)
; c13	  = point_light's attenuation
; c12	  = material ambient * point_light.ambient
; c11	  = material.diffuse * point_light.diffuse
; c10	  = point_light's position in world space
; c9	  = material.specular * dir_light.specular
; c8	  = material.diffuse * dir_light.diffuse
; c7	  = ambient color + emmisive color
; c6	  = eye's direction in world space
; c2-c5   = view matrix * projection matrix (from world space to cuboid space)
; c1	  = dir_light's direction in world space
; c0	  = {1, power, 0, 765.01};
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; oPos	  = Output position
; oD0	  = Diffuse
; oD1	  = Specular
; oT0	  = texture coordinates
;------------------------------------------------------------------------------

; ============ Morph vertex ================

; Calculate morph position and normal

mov r7, v0	; position in r7
mov r8, v3	; normal in r8

mad r7, c14.xxxx, v5, r7
mad r8, c14.xxxx, v6, r8

mad r7, c14.yyyy, v7, r7
mad r8, c14.yyyy, v8, r8

mad r7, c14.zzzz, v9, r7
mad r8, c14.zzzz, v10, r8

mad r7, c14.wwww, v11, r7
mad r8, c14.wwww, v12, r8

mov r7.w, c0.x	; set w to 1

; normalize normal
dp3 r8.w, r8, r8
rsq r8.w, r8.w
mul r8, r8, r8.w

; ============ Transform position and normal from model space to world space ==========

; remap matrix indices from float (0.0-1.0)
mul r1, v2.zyxw, c0.wwww

; Set 1
mov a0.x, r1.x
m4x3 r4, r7, c[a0.x + 15]
m3x3 r5, r8, c[a0.x + 15] 

; Transfrom position from world space to cuboid space and output it
mov r4.w, c0.x
m4x4 oPos, r4, c2

; Do we need to re-normalize normal ? We just did a rotation, so...
; dp3 r5.w, r5, r5
; rsq r5.w, r5.w
; mul r5, r5, r5.w

; ============ Calculate dynamic point light's diffuse ============

; point light pos - vertex position in world space
add r10.xyz, c10, -r4.xyz

; Normalize vector VERTEX_TO_LIGHT and calculate distance
; d = distance
dp3 r10.w, r10, r10  	; r10.w = d * d = (x*x) + (y*y) + (z*z)
rsq r11.w, r10.w     	; r11.w = 1 / d = 1 / ||V|| = 1 / sqrt(r10.w)
mul r11, r10, r11.w	; r11 = Normalized vector

mov r8, c0.zzzz		; clear r8
dp3 r8.x, r5, r11 	; N dot L
lit r8, r8		; compute light

; Calculate the attenuation
; r10.w = d * d
; r11.w = 1 / d
; r9 = (1, d*d*1/d, d*d, 1/d)
dst r9, r10.w, r11.w

dp3 r9.x, r9, c13	; (a0 + a1*d + a2*d*d)
rcp r9.x, r9.x

mul r1, r8, r9.xxxx	; Scale with the attenuation
mul r8, r1.y, c11	; Multiply with point_light's diffuse

; ============ Calculate directional light's diffuse ============

mov r1, c0.zzzz		; clear r1
dp3 r1.x, r5, -c1     	; normal dot light (N * L)
lit r1, r1

mad r0, r1.y, c8, r8   	; Multiply with dir_light's diffuse then add point_light's diffuse
mad r0, r9.x, c12, r0  	; Add point_light's ambient * attenuation
add r0, r0, c7		; Add other ambient
min oD0, r0, c0.x     	; output diffuse, clamp if > 1

mov oD1, c0.zzzx   	; output specular as 0

; Copy texture coordinate
mov oT0, v4

